package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.api.cache.prefix.BasekeyPrefix;
import cn.wolfcode.luowowo.api.cache.prefix.UserInfoKeyPrefix;
import cn.wolfcode.luowowo.api.cache.service.IRedisService;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class RedisServiceImpl implements IRedisService{
    @Autowired
    private RedisTemplate redisTemplate;


    public <T> void set(BasekeyPrefix prefix, String phone, T value) {
        //真实的key
        String realKey = prefix.getPrefix()+":"+phone;
        //将value值转换成字符串
        String realValue = bean2String(value);
        //获取操作redis的操作器
        ValueOperations op = redisTemplate.opsForValue();
        if(prefix.getTime() > 0){
            op.set(realKey,realValue,prefix.getTime(), TimeUnit.SECONDS);
        }else{
            //不失效
            op.set(realKey,realValue);
        }
    }
    //将value值转换成字符串
    private <T> String bean2String(T value) {
        if(value.getClass() == int.class || value.getClass() == Integer.class){
            return value + "";
        }
        if(value.getClass() == long.class || value.getClass() == Long.class){
            return value + "";
        }
        if(value.getClass() == float.class || value.getClass() == Float.class){
            return value + "";
        }
        if(value.getClass() == double.class || value.getClass() == Double.class){
            return value + "";
        }
        if(value.getClass() == byte.class || value.getClass() == Byte.class){
            return value + "";
        }
        if(value.getClass() == String.class){
            return value + "";
        }
        return JSON.toJSONString(value);
    }

    public <T> void setFollow(BasekeyPrefix prefix, Long id, T code) {
        //真实的key
        String realKey = prefix.getPrefix()+":"+id;
        //将value值转换成字符串
        String realValue = bean2String(code);
        //获取操作redis的操作器
        SetOperations set = redisTemplate.opsForSet();
        set.add(realKey,realValue);

    }



    public boolean exists(BasekeyPrefix prefix, String phone) {
        String realKey = prefix.getPrefix()+":"+phone;
        return redisTemplate.hasKey(realKey);
    }


    public String get(BasekeyPrefix prefix, String phone) {
        //获取真实的key
        String realKey = prefix.getPrefix()+":"+phone;
        return redisTemplate.opsForValue().get(realKey)+"";
    }

    public <T> T get(BasekeyPrefix prefix, String token, Class<T> clz) {
        String realKey = prefix.getPrefix()+":"+token;
        String s = redisTemplate.opsForValue().get(realKey)+"";
        return JSON.parseObject(s,clz);
    }

    public void expire(BasekeyPrefix prefix, String token) {
        String realKey = prefix.getPrefix()+":"+token;
        redisTemplate.expire(realKey,prefix.getTime(),TimeUnit.SECONDS);
    }

    public Set getKeysByPattern(String pattern) {
        return redisTemplate.keys(pattern);
    }

    public <T> T getByRealKey(String realKey, Class<T> clz) {
        String s = redisTemplate.opsForValue().get(realKey) + "";
        if(clz == String.class){
            return (T) s;
        }
        return JSON.parseObject(s,clz);
    }




    public void addScore(BasekeyPrefix keyPrefix, String key, String value, int score) {
        String realKey = keyPrefix.getPrefix() + key;
        redisTemplate.opsForZSet().incrementScore(realKey,value,score);
    }

    public <T> List<T> reversRange(BasekeyPrefix keyPrefix, String key, int start, int end, Class<T> clz) {
        String realKey = keyPrefix.getPrefix() + key;
        //用于存放对象
        ArrayList<T> list = new ArrayList<>();
        //查询出了所有的vo对象的key
        Set set = redisTemplate.opsForZSet().reverseRange(realKey, start, end);
        if(set == null){
            return list;
        }

        for (Object o : set) {
            String voKey = o.toString();
            list.add(this.getByRealKey(voKey, clz));
        }
        return list;
    }




    public boolean hasZsetValue(BasekeyPrefix prefix, String ComKey, BasekeyPrefix voPrefix, String VoKey, Long sid) {
        String realKey = prefix.getPrefix()+ComKey;
        String value = voPrefix.getPrefix()+VoKey+ sid;
        Long rank = redisTemplate.opsForZSet().rank(realKey, value);

        return rank != null;
    }

    public void addCommonScore(BasekeyPrefix basekeyPrefix, String key, String value, int score) {
        String realKey = basekeyPrefix.getPrefix() + key;
        redisTemplate.opsForZSet().incrementScore(realKey,value,score);
    }




    public <T> List<T> reversRangeSet(UserInfoKeyPrefix prefix, String key, Class<T> clz) {
        String realKey = prefix.getPrefix() + key;
        //用于存放对象
        ArrayList<T> list =null;
        Set set = redisTemplate.opsForSet().members(realKey);

        if(clz == String.class){
            list = new ArrayList<>(set);
            return list;
        }

        list = new ArrayList<>();
        for (Object o : set) {
            String voKey = o.toString();
            list.add(JSON.parseObject(voKey,clz));
        }
        return list;

    }

}
